/*
 ####        # 
 #           #
 ## ### #  # #
 #  #-# #\ # #
 #  # # # \# ####
 Author: Felipe de Andrade Neves Lavratti

 Copyright: There are no restrictions. Use as you want.	  
*/

/*
	LPC 2478
	+ TFT DISPLAY
	+ TOUCH PANNEL
	+ SWIM
	+ SDRAM

	Get more at: selivre.wordpress.com
*/

#include "sdram.h"

void SDRAM_Init (void)
{
  UNS_32 i;
  volatile UNS_32 Dummy;

  PINSEL5 &= 0x00FCFCC0;
  PINSEL5 |= 0x55010115;
  PINMODE5&= 0x00FCFCC0;
  PINMODE5|= 0xAA02022A;
  PINSEL6  |= 0x55555555;
  PINMODE6 |= 0xAAAAAAAA;
  PINSEL7  |= 0x55555555;
  PINMODE7 |= 0xAAAAAAAA;
  PINSEL8 &= 0xC0000000;
  PINSEL8 |= 0x55555555;
  PINMODE8&= 0xC0000000;
  PINMODE8|= 0x2AAAAAAA;
  PINSEL9 &= 0xFFF3FFFF;
  PINSEL9 |= 0x00040000;
  PINMODE9&= 0xFFF3FFFF;
  PINMODE9|= 0x00080000;


  PCONP 	       |= 0x800;
  EMC_CTRL     		= 1;
  EMC_DYN_RD_CFG 	= 1;
  EMC_DYN_RASCAS0&=0xFFFFFFFF; EMC_DYN_RASCAS0|=0x300;
  EMC_DYN_RASCAS0|=0x3;
  EMC_DYN_RP= 1;
  EMC_DYN_RAS = 2;
  EMC_DYN_SREX = 3;
  EMC_DYN_APR = 1;
  EMC_DYN_DAL =3+2;
  EMC_DYN_WR = 3;
  EMC_DYN_RC = 3;
  EMC_DYN_RFC = 3;
  EMC_DYN_XSR = 3;
  EMC_DYN_RRD = 0;
  EMC_DYN_MRD = 3;

  // 11 row, 8 - col, SDRAM
  EMC_DYN_CFG0 = 0 | (1u << 14)
		| (0u << 12)
		| (1u << 9)
		| (2u << 7);

  // JEDEC General SDRAM Initialization Sequence
  // DELAY to allow power and clocks to stabilize ~100 us
  // NOP
  EMC_DYN_CTRL = 0x0183;
  delayMs(100);
  // PALL
  EMC_DYN_CTRL 	   |= 0x100; EMC_DYN_CTRL &= 0xFFFFFF7F;
  EMC_DYN_RFSH 		= 1;
  delayMs(100);
  EMC_DYN_RFSH 		= 21;
  // COMM
  EMC_DYN_CTRL|=0x80; EMC_DYN_CTRL&=0xFFFFFEFF;

  Dummy = *(volatile unsigned int *)((UNS_32)&SDRAM_BASE_ADDR + (0x32UL << (12)));

  // NORM
  EMC_DYN_CTRL = 0x0000;  //Issue SDRAM norm command ; CLKOUT stop;All clock enables low
  EMC_DYN_CFG0|=0x80000; //Buffer enabled for accesses to DCS0 chip

  delayMs(200);
}



unsigned int  SDRAM_Test (void)
{
  UNS_32 i;

  // 32 bits access
  for (i = 0; i < 0x400000; i+=sizeof(unsigned int))
  {
    *(unsigned int *)((unsigned int )&SDRAM_BASE_ADDR+(unsigned int )i) = i;
  }
  for (i = 0; i < 0x400000; i+=sizeof(unsigned int ))
  {
    if (*(unsigned int *)((unsigned int )&SDRAM_BASE_ADDR+(unsigned int )i) != i)
    {
 //     printf("Verification error on address : 0x%x\n",(UNS_32)&SDRAM_BASE_ADDR+i);
      return(FALSE);
    }
  }
  // 16 bits access
  for (i = 0; i < 0x10000; i+=sizeof(unsigned short))
  {
    *(unsigned short*)((unsigned int)&SDRAM_BASE_ADDR+i) = i;
  }
  for (i = 0; i < 0x10000; i+=sizeof(unsigned short))
  {
    if (*(unsigned short*)((unsigned int)&SDRAM_BASE_ADDR+i) != i)
    {
//    	printf("Verification error on address : 0x%x\n",(UNS_32)&SDRAM_BASE_ADDR+i);
    	return(FALSE);
    }
  }
  // 8 bits access
  for ( i = 0; i < 0x100; i+=sizeof(unsigned char))
  {
    *(unsigned char*)((unsigned int)&SDRAM_BASE_ADDR+i) = i;
  }
  for (i = 0; i < 0x100; i+=sizeof(unsigned char))
  {
    if (*(unsigned char*)((unsigned int)&SDRAM_BASE_ADDR+i) != i)
    {
 //   	printf("Verification error on address : 0x%x\n",(UNS_32)&SDRAM_BASE_ADDR+i);
      return(FALSE);
    }
  }
  return(TRUE);
}
